<?
/*	Created by Alexander Alexandrov aka SS

			hazg@mail.ru				*/


define('SSLIB_Page', TRUE);

if(!defined("SSLIB_Html")) die("Html class missing");
if(!defined("SSLIB_Request")) die("Request class missing");
if(!defined("SSLIB_Template")) die("Template class missing");

$g_page = null;
function P($key, $val, $add = true){Page::Custom($key, $val, $add);}
class ErrPage extends Err
{
	function __construct($message, $code = 0)
	{
		parent::__construct($message, $code);
	}
	function __toString()
	{
		return sslib_exception_format($this->getCode(), $this->getMessage(), $this->getFile(), $this->getLine(), "������ ��������",  $this);
	}
}
class Page
{
	private $arr;
	private $templatefile;
	private $title;
	private $cssfiles;
	private $jsfiles;
	private $js;
	private $style;
	private $drawed;
	private $lastmodif;
	private $cachepath;
	private $customcachepath;
	
	static function ValidateObject()
	{
		global $g_page;
		return empty($g_page)?false:true;
	}
	
	private function needCaching()
	{
		return (empty($this->lastmodif)?false:true);
	}
	private function getCachePath()
	{
		global $sslib_citeroot;
		$str = $_SERVER['REQUEST_URI'];
		if($this->customcachepath)
			$str.=$this->customcachepath;
		foreach($_REQUEST as $k => $v)
		{
			$str.="&$k=$v";
		}
			
		return $sslib_citeroot.'cache/'.md5($str);
	}
	private function needUpdate()
	{
		$path = $this->getCachePath();
		if(!file_exists($path))
			return true;
			
		if(filemtime($path) < $this->lastmodif)
			return true;
		return false;
	}
	private function saveAndGetCache($arr, $templ)
	{
		$str = Template::CompileFile($arr, $templ);
		
		file_put_contents($this->getCachePath(), gzdeflate($str));
		return $str;	
	}
	
	static function TryFromCache()
	{
		global $g_page;
		
		if($g_page->needCaching() && !$g_page->needUpdate())
		{
			echo gzinflate(file_get_contents($g_page->getCachePath()));
			$g_page->drawed = true;
			exit;
		}
	}
	function Page($templatefile, $lastmodif = null, $custompath = null)
	{
		$this->customcachepath = $custompath;
		$this->drawed = false;
		$this->cachepath = null;
		
		
		
		
		if(!empty($GLOBALS['g_page'])) die("Page already created!");
		
		$GLOBALS['g_page'] = $this;
		
		
		
		Page::Expire($lastmodif);
		$this->TryFromCache();
		
		
		
		$this->templatefile = $templatefile;
		ob_start();
	}
	function __destruct()
	{
	    //print "<b>PAGE DESTRUCT</b>";
		if(!$this->drawed){die("Page created, but does't drawed!");}
	}
	static function Draw()
	{
		$g_page = $GLOBALS['g_page'];
		if(empty($g_page)) die("Page object does't created!");
		if($g_page->drawed) die("page allready drawed.");
		$g_page->drawed = true;
		
		//header('Expire: 'gmdate());
		
		Page::Content(ob_get_clean());
		/*Page::Content(ob_get_clean().
		(Sslib::Debug()?'<div style="text-align:center;position:relative; z-index:1000;margin:2px;padding:2px;background-color: buttonface; border: 1px solid buttonshadow;font:message-box; color: windowtext;">DEBUG MODE</div>':'')
		
		);*/
		
		
		
		//STYLE
		if(!empty($g_page->style))
			$g_page->style = '<style type="text/css">'.$g_page->style.'</style>';
		//JS
		if(!empty($g_page->js))
			$g_page->js = '<script type="text/javascript">'.$g_page->js.'</script>';
		//TITLE
		if(!empty($g_page->title))
			$g_page->title = '<title>'.$g_page->title.'</title>';
		//CSS FILES
		if(!empty($g_page->cssfiles))
		{
			$cssfiles = split(" ", trim($g_page->cssfiles));
			$g_page->cssfiles = "";
			foreach($cssfiles as $f)
				$g_page->cssfiles.= '<link rel="stylesheet" type="text/css" media="screen" href="'.trim($f).'" />';
		}
		//JS FILES
		if(!empty($g_page->jsfiles))
		{
			$jsfiles = split(" ", trim($g_page->jsfiles));
			$g_page->jsfiles = "";
			foreach($jsfiles as $f)
				$g_page->jsfiles.= '<script type="text/javascript" src="'.trim($f).'"></script>';
		}
		$g_page->arr['head'] 
		= 
		'<meta http-equiv="Content-Type" content="text/html; charset='.Sslib::Variable('page.charset')."\">".$g_page->title.$g_page->style.$g_page->cssfiles.$g_page->jsfiles.$g_page->js;
		
		/*echo "NEED? ".$g_page->needCaching()."<br />";
		echo "UPDATE? ".$g_page->needUpdate();*/
		if($g_page->needCaching() && $g_page->needUpdate())
		{
			//echo "save to cache";
			echo $g_page->saveAndGetCache($g_page->arr, $g_page->templatefile);
		}
		else
		{
			$template = /*Html::Exec(*/file_get_contents($g_page->templatefile);/*, $g_page->templatefile);*/
			$template = str_replace('{content}', $g_page->arr['content'], $template);
			unset($g_page->content);
			print Template::Compile($g_page->arr, $template, $g_page->templatefile);
		}
	}
	const INSERT_REPLACE 	= "0";
	const INSERT_END 		= "1";
	const INSERT_BEGIN 		= "2";
	static function Location($url)
	{
		header('Location: '.$url);
	}
	static function Content		($text, $add = Page::INSERT_REPLACE)	
	{
		Page::Set('content', 	$text, $add);
	}
	static function Title		($text, $add = Page::INSERT_REPLACE)	
	{
		$g_page = $GLOBALS['g_page'];
		switch($add)
		{
			case Page::INSERT_REPLACE:	$g_page->title = $text;break;
			case Page::INSERT_END:		$g_page->title .= $text;break;
			case Page::INSERT_BEGIN:	$g_page->title = $text.$g_page->title;break;
		}
	}
	static function JsFile		($text)	
	{
		$g_page = $GLOBALS['g_page'];$g_page->jsfiles.=$text." ";
	}
	static function CssFile		($text)	
	{
		$g_page = $GLOBALS['g_page'];$g_page->cssfiles.=$text." ";
	}
	static function Style		($text, $add = Page::INSERT_END)
	{
		$g_page = $GLOBALS['g_page'];
		switch($add)
		{
			case Page::INSERT_REPLACE:	$g_page->style = $text;break;
			case Page::INSERT_END:		$g_page->style .= $text;break;
			case Page::INSERT_BEGIN:	$g_page->style = $text.$g_page->style;break;
		}
	}
	static function JavaScript		($text, $add = Page::INSERT_END)
	{
		$g_page = $GLOBALS['g_page'];
		switch($add)
		{
			case Page::INSERT_REPLACE:	$g_page->js = $text;break;
			case Page::INSERT_END:		$g_page->js .= $text;break;
			case Page::INSERT_BEGIN:	$g_page->js = $text.$g_page->js;break;
		}
	}
	function _set($key, $val, $add = true)
	{
		
		if(strtolower($key) === "head")
			throw new Err('"Head" is reserved template key!');
		if($add)
		{
			if(isset($this->arr[$key]))
				$this->arr[$key]	.= $val;
			else
				$this->arr[$key]	= $val;
		}
		else 	{	$this->arr[$key]	= $val;		}
	}
	static function Set($key_or_arr, $val = null, $add = true)
	{
		global $g_page;
		if(is_array($key_or_arr) === TRUE)
		{
			foreach ($key_or_arr as $k=>$v)
			{
				$g_page->_set($k, $v, $add);
			}
		}
		else
		{
			$g_page->_set($key_or_arr, $val, $add);
		}
	}
	static function Get($key)
	{
		global $g_page;
		if(array_key_exists($key, $g_page->arr))
			return $g_page->arr[$key];
		return FALSE;
	}
	static function Expire($arr)
	{
		if(is_array($arr))
		{
			if(array_key_exists('modif', $arr))
				$arr = $arr['modif'];
			else if(array_key_exists('max', $arr))
				$arr = $arr['max'];
			else 
				throw new Err('$arr is array, but there is no "modif" key!');
		}
		$g_page = $GLOBALS['g_page'];
		
		$arr = strtotime($arr);
		
		if($g_page->lastmodif < $arr)
		{
			$g_page->lastmodif = $arr;
		}
	}
	
}
?>